package com.quectel.cms.controller.partyeducation;


import com.quectel.cms.controller.BaseController;
import com.quectel.cms.util.SessionHolder;
import com.quectel.cms.vo.partyeducation.LibraryCheckReportReq;
import com.quectel.cms.vo.partyeducation.UploadResourceResp;
import com.quectel.constant.core.partyeducation.PartyEducationLibraryConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.constant.global.UploadConstants;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.core.module.partyeducation.dto.PartyEducationLibraryDto;
import com.quectel.core.module.partyeducation.dto.PartyEducationLibraryUserDto;
import com.quectel.core.module.partyeducation.service.PartyEducationLibraryService;
import com.quectel.sys.module.sys.dto.SysUserDto;
import com.quectel.sys.module.sys.service.SysUserService;
import com.quectel.util.common.*;
import com.quectel.util.kit.MinIOUtils;
import com.quectel.util.kit.StorageKit;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 *
 * @author ryan
 * @email ryan.ran@quectel.com
 * @date 2023/06/13 17:18
 */
@RestController
@RequestMapping("partyEducationLibrary")
@Tag(name = "PartyEducationLibraryController", description = "党建文库相关api")
public class PartyEducationLibraryController extends BaseController {

    @DubboReference
    private PartyEducationLibraryService partyEducationLibraryService;
    @DubboReference
    private SysUserService sysUserService;

    @PostMapping("report")
    @Operation(summary = "预览请求")
    public Response<Object> report(@RequestBody @Validated LibraryCheckReportReq req){
        PartyEducationLibraryDto partyEducationLibraryDto = partyEducationLibraryService.selectCacheById(req.getId());
        if (Objects.nonNull(partyEducationLibraryDto)) {
            Long userId = Objects.requireNonNull(SessionHolder.getSysUser()).getUserId();
            SysUserDto sysUserDto = sysUserService.selectCacheById(userId);
            PartyEducationLibraryUserDto partyEducationLibraryUserDto = CopyUtils.copyObj(sysUserDto, PartyEducationLibraryUserDto.class);
            partyEducationLibraryUserDto.setUserId(userId);
            partyEducationLibraryUserDto.setCheckTime(new Date());
            partyEducationLibraryUserDto.setCheckType(req.getCheckType());
            partyEducationLibraryUserDto.setLibraryId(partyEducationLibraryDto.getId());
            partyEducationLibraryUserDto.setPartyId(partyEducationLibraryDto.getPartyId());
            partyEducationLibraryService.check(partyEducationLibraryUserDto);
        }
        return Response.ok();
    }

    @GetMapping("check/{id}/{checkType}")
    @Operation(summary = "资源访问")
    public void check(@PathVariable Long id, @PathVariable Byte checkType, HttpServletResponse httpServletResponse) {
        PartyEducationLibraryDto partyEducationLibraryDto = partyEducationLibraryService.selectCacheById(id);
        if (Objects.isNull(partyEducationLibraryDto)) {
            try {
                httpServletResponse.getOutputStream().write("Resource not exists".getBytes(StandardCharsets.UTF_8));
            } catch (IOException e) {
                logger.error("Party education library resource not found, response write error.");
            }
            return ;
        }

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (partyEducationLibraryService.queryTotal(params) <= 0) {
            try {
                httpServletResponse.getOutputStream().write(SystemConstants.ILLEGAL_MSG.getBytes(StandardCharsets.UTF_8));
            } catch (IOException e) {
                logger.error("Party education library resource unauthorized, response write error.");
            }
            return ;
        }

        if (PartyEducationLibraryConstants.StatusEnum.DISABLE.getStatus().equals(partyEducationLibraryDto.getStatus())) {
            try {
                httpServletResponse.getOutputStream().write(SystemConstants.ILLEGAL_MSG.getBytes(StandardCharsets.UTF_8));
            } catch (IOException e) {
                logger.error("Party education library status is disable, response write error.");
            }
            return ;
        }

        if (PartyEducationLibraryConstants.CheckTypeEnum.DOWNLOAD.getCheckType().equals(checkType)
                && PartyEducationLibraryConstants.AllowDownloadEnum.DISABLE.getAllowStatus().equals(partyEducationLibraryDto.getAllowDownload())) {
            try {
                httpServletResponse.getOutputStream().write(SystemConstants.ILLEGAL_MSG.getBytes(StandardCharsets.UTF_8));
            } catch (IOException e) {
                logger.error("Party education library download status is disable, response write error.");
            }
            return ;
        }
        ServletUtils.write(
                httpServletResponse,
                StorageKit.getObject(partyEducationLibraryDto.getResourceCode()),
                partyEducationLibraryDto.getResourceName()
        );
    }

    /**
     * 文库资源上传
     *
     * @param request
     * @return
     */
    @PostMapping("uploadResource")
    @Operation(summary = "文库资源上传")
    public Response<UploadResourceResp> uploadCert(MultipartHttpServletRequest request) {
        Iterator<String> fileNames = request.getFileNames();
        while (fileNames.hasNext()) {
            String next = fileNames.next();
            List<MultipartFile> files = request.getFiles(next);
            for (MultipartFile file : files) {

                try {
                    String filename = file.getOriginalFilename();
                    UploadResourceResp.UploadResourceRespBuilder builder = UploadResourceResp.builder().resourceName(filename);

                    // 文件上传
                    int i = 0;
                    for (i = 0; i < UploadConstants.FILE_ACCEPT_TYPE.length; i++) {
                        if (Objects.requireNonNull(file.getOriginalFilename()).endsWith(UploadConstants.FILE_ACCEPT_TYPE[i])) {
                            break;
                        }
                    }
                    if (i >= UploadConstants.FILE_ACCEPT_TYPE.length) {
                        return Response.error("不支持的文件格式");
                    }

                    File tempFile = null;
                    try {
                        tempFile = MyFileUtils.writeFileToTempDir(file.getInputStream(), file.getOriginalFilename(), false);
                        String code = MinIOUtils.getDefaultClient().fastPutObjectToBucketObtainObject(null, "library",tempFile, Boolean.TRUE);
                        builder.resourceCode(code);
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if (tempFile != null && tempFile.exists()) {
                            tempFile.delete();
                        }
                    }

                    return Response.<UploadResourceResp>ok().wrap(builder.build());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return Response.error("上传失败");
    }

    /**
     * 分页查询
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("list")
    @RequirePermissions(values = "partyEducationLibrary:list")
    @Operation(summary = "分页获取党建文库列表")
    public Response<Page<PartyEducationLibraryDto>> list(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize
    ) {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());
        int total = partyEducationLibraryService.queryTotal(request.getParams());

        List<PartyEducationLibraryDto> list = null;
        if (total > 0) {
            list = partyEducationLibraryService.queryList(request.getParams());
        } else {
            list = new ArrayList<>();
        }

        Page<PartyEducationLibraryDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<PartyEducationLibraryDto>>ok().wrap(page);
    }

    /**
     * 编辑查询反显
     *
     * @param id
     * @return
     */
    @GetMapping("infoForEdit/{id}")
    @RequirePermissions(values = "partyEducationLibrary:edit")
    @Operation(summary = "在编辑时根据id查询党建文库详情")
    public Response<PartyEducationLibraryDto> infoForEdit(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (partyEducationLibraryService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PartyEducationLibraryDto partyEducationLibraryDto = partyEducationLibraryService.selectById(id);

        return Response.<PartyEducationLibraryDto>ok().wrap(partyEducationLibraryDto);
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @GetMapping("info/{id}")
    @RequirePermissions(values = "partyEducationLibrary:info")
    @Operation(summary = "根据id查询党建文库的详情")
    public Response<PartyEducationLibraryDto> info(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (partyEducationLibraryService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PartyEducationLibraryDto partyEducationLibraryDto = partyEducationLibraryService.selectById(id);

        return Response.<PartyEducationLibraryDto>ok().wrap(partyEducationLibraryDto);
    }

    /**
     * 保存
     *
     * @param partyEducationLibraryDto
     * @return
     */
    @PostMapping("save")
    @RequirePermissions(values = "partyEducationLibrary:edit")
    @Operation(summary = "新增党建文库")
    public Response<Object> save(@RequestBody @Validated PartyEducationLibraryDto partyEducationLibraryDto) {

        //填充基础数据
        fillSaveCommonData(partyEducationLibraryDto);

        partyEducationLibraryService.save(partyEducationLibraryDto);

        return Response.ok();
    }


    /**
     * 修改
     *
     * @param partyEducationLibraryDto
     * @return
     */
    @PostMapping("update")
    @RequirePermissions(values = "partyEducationLibrary:edit")
    @Operation(summary = "根据id修改党建文库")
    public Response<Object> update(@RequestBody  @Validated PartyEducationLibraryDto partyEducationLibraryDto) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(partyEducationLibraryDto.getId()));
        if (partyEducationLibraryService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        //填充基础数据
        fillEditCommonData(partyEducationLibraryDto);

        partyEducationLibraryService.updateById(partyEducationLibraryDto);

        return Response.ok();
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @PostMapping("delete")
    @RequirePermissions(values = "partyEducationLibrary:delete")
    @Operation(summary = "根据多条记录id批量删除党建文库")
    public Response<Object> delete(@RequestBody Long[] ids) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);

        for (Long id : ids) {
            params.remove(SystemConstants.ENTITY_ID_FLAG);
            params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));

            if (partyEducationLibraryService.queryTotal(params) <= 0) {
                return Response.error(SystemConstants.ILLEGAL_MSG);
            }
        }

        partyEducationLibraryService.deleteBatch(ids);

        return Response.ok();
    }
}
